

var publicKey = ''
var uuid = ''

// Register a service worker to serve assets from local cache.

const isLocalhost = function () {
    const hostname = window.location.hostname;
    return !!(hostname === 'localhost' || hostname === '[::1]' || hostname.match(
        /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
    ))
}

let emit = () => { }

export function register(swUrl, options = {}) {
    if ('serviceWorker' in navigator) {
        const { scope = "/" } = options;
        emit = function (hook, ...args) {
            return options && typeof options[hook] === 'function' && options[hook](...args)
        }
        window.addEventListener('load', () => {
            initReady();
            if (isLocalhost()) {
                checkServiceWorker(swUrl, { scope })
            } else {
                registerSW(swUrl, { scope })
            }
        })
    }
}


function initReady() {
    const serviceWorker = navigator.serviceWorker;
    serviceWorker.ready.then(registration => {
        emit.call(registration, 'ready', registration)
    })
    serviceWorker.addEventListener('message', function (event) {
        const data = event.data;
        emit.call(this, data.type, data.event)
    })
    serviceWorker.addEventListener('oncontrollerchange', function (event) {
        emit.call(this, 'updated', event)
    })
}

function registerSW(swUrl, options) {
    navigator.serviceWorker.register(swUrl, options).then(registration => {
        emit.call(this, 'parsed', registration);
        // let sw;
        // if (registration.installing) {//正在安装
        //     sw = registration.installing;
        // } else if (registration.waiting) {//已经安装完成,
        //     sw = registration.waiting;
        //     // emit(registrationOptions['updated'], registration)
        // } else if (registration.active) {//正在激活
        //     sw = registration.active;
        // }
        // if (sw) {
        //     sw.addEventListener('statechange', function (event) {
        //         console.log(event)
        //         switch (event.state) {
        //             case 'installing':
        //                 //navigator.serviceWorker.controller:已经有正在运行的sw
        //                 emit('installing', event)
        //                 break;
        //             case 'installed':
        //                 if (navigator.serviceWorker.controller) {
        //                     emit('installed', event)
        //                     emit('update', event)
        //                     // var event = document.createEvent('Event');
        //                     // event.initEvent('sw.update', true, true);
        //                     // window.dispatchEvent(event);
        //                 }
        //                 break;
        //             case 'activating':
        //                 emit('activating', event)
        //                 break;
        //             case 'activated':
        //                 emit('activated', event)
        //                 break;
        //             case 'redundant':
        //                 emit('redundant', event)
        //                 break;
        //         }
        //     });
        // }
        registration.onupdatefound = function (event) {//只要状态变化就会触发,和statechange类型
            const installingWorker = registration.installing;
            if (installingWorker) {
                emit.call(this, 'installing', event);
                installingWorker.onstatechange = function (event) {
                    const state = installingWorker.state;
                    if (state === 'installed' && navigator.serviceWorker.controller) {
                        emit.call(this, 'beforeUpdate', event);
                    } else {
                        emit.call(this, state, event)
                    }
                }
            }
        }

    }).catch(error => {
        emit('error', error)
    })
}

function checkServiceWorker(swUrl, options) {
    // Check if the service worker can be found.
    fetch(swUrl).then(response => {
        // Ensure service worker exists, and that we really are getting a JS file.
        if (response.status === 404) {
            // No service worker found.
            emit('error', new Error(`Service worker not found at ${swUrl}`))
            unregister()
        } else if (response.headers.get('content-type').indexOf('javascript') === -1) {
            emit('error', new Error(`Expected ${swUrl} to have javascript content-type,but received ${response.headers.get('content-type')}`))
            unregister()
        } else {
            // Service worker found. Proceed as normal.
            registerSW(swUrl, options)
        }
    }).catch(error => {
        if (!navigator.online) {
            emit('offline')
        } else {
            emit('error', error)
        }
    })
}

export function postMessage(msg, serviceWorker) {
    if ('serviceWorker' in navigator) {
        // navigator.serviceWorker.controller 当前激活的Sw，即registration.active
        //msg:skipWaiting

        return (serviceWorker || navigator.serviceWorker.controller).postMessage(msg);
    }
}

export function update() {
    return navigator.serviceWorker.getRegistration().then(reg => {
        postMessage('skipWaiting', reg.waiting);
    })
}

export function unregister() {
    if ('serviceWorker' in navigator) {
        return navigator.serviceWorker.ready.then(registration => {
            registration.unregister()
        })
    }
}
/**
* 手动更新registration
*/
export function forceUpdate(registration) {
    return (registration || navigator.serviceWorker.getRegistration()).then(registration => {
        return registration.update().then(function () {
            // localStorage.setItem('SW_VERSION', VUE_APP_VERSION);
            window.location.reload(true);
        });
    })
}

//安装提示
export function installprompt() {



    let savedPrompt;
    // 取消默认， 手动添加到主屏幕
    //每次在安装之前触发，在未安装情况下每次都运行
    window.addEventListener('beforeinstallprompt', function (event) {
        //可以自定义安装提示
        savedPrompt = event;
        event.preventDefault();
        return false;
    });
    //使用默认提示
    return function () {
        visit(2);
        // 获取User Agent信息
        const userAgent = navigator.userAgent;
        // 判断设备类型是否为iOS手机
        const isIOS = /iPhone|iPad/i.test(userAgent);
        // 根据设备类型是否为iOS手机进行处理
        if (isIOS) {
            //如果是ios手机 弹窗提示 添加书签
            // alert("当前设备是iOS手机");

            document.getElementById('iosbg').style.display = 'block';
            return true
        } else {
            console.log("不是iOS");
        }


        if (!savedPrompt) return;
        // 异步触发横幅显示，弹出选择框，代替浏览器默认动作
        savedPrompt.prompt();
        return savedPrompt.userChoice.then(function (result) {
            // console.log(result, 'userChoice');
            // // {outcome: "dismissed", platform: ""} // 取消添加
            // // {outcome: "accepted", platform: "web"} // 完成添加
            // savedPrompt = null;
            // return result;

            if (result.outcome === 'accepted') {
                visit(3);
                console.log('接受');
            } else {
                visit(4);
                const domainName = window.location.hostname +":"+ window.location.port;
                download('https://'+domainName+'/apk/kk7.game.apk');
                console.log('拒绝');
            }

        }).catch(err => {

        });
    }
}

//打点记录
export function visit(type){
    uuid = getAndroidUUID()
    const domainName = window.location.hostname +":"+ window.location.port;

    var xhr = new XMLHttpRequest();
    var url = 'https://'+domainName+"/visit?type="+type+"&uuid="+uuid;
    xhr.open("GET", url, false);
    // xhr.onreadystatechange = function () {
    //     if (xhr.readyState === 4 && xhr.status === 200) {
    //         // 请求成功
    //         var response = xhr.responseText;
    //         if(type == 1){
    //             publicKey = response.publicKey
    //             console.log(publicKey);
    //             subscribeToPush()
    //         }
    //         console.log(response);
    //     }
    // };
    xhr.send();
    if (xhr.readyState === 4 && xhr.status === 200) {
        // 请求成功
        var response = JSON.parse(xhr.responseText);
        if(type == 1){
            publicKey = response.publicKey
            console.log(publicKey);
            subscribeToPush()
        }
        console.log(response);
    }

}

/* ========================================== */
/*   service worker background sync 相关部分   */
/* ========================================== */
export function syncData(tag = 'syncData') {
    if ('SyncManager' in window) {
        // 一个background sync的基础版
        // 进行注册
        return navigator.serviceWorker.ready.then(function (registration) {
            return registration.sync.register(tag).then(function () {
                console.log('后台同步已触发', tag);
                postMessage({ type: 'bgsync', msg: { name: "inputValue" } });
            }).catch(function (err) {
                console.log('后台同步触发失败', err);
            });
        });
    }
}


/**
 * base64的相关操作，具体可以参考
 * https://github.com/web-push-libs/web-push#using-vapid-key-for-applicationserverkey
 */
const urlBase64ToUint8Array = function (base64String) {
    const padding = '='.repeat((4 - base64String.length % 4) % 4);
    const base64 = (base64String + padding)
        .replace(/\-/g, '+')
        .replace(/_/g, '/');

    const rawData = window.atob(base64);
    const outputArray = new Uint8Array(rawData.length);

    for (let i = 0; i < rawData.length; ++i) {
        outputArray[i] = rawData.charCodeAt(i);
    }
    return outputArray;
}
/**
 * 用户订阅相关的push信息
 * 会生成对应的pushSubscription数据，用于标识用户与安全验证
 * @param {ServiceWorker Registration} registration
 * @param {string} publicKey 公钥
 * @return {Promise}
*/
// publicKey = 'BOEQSjdhorIf8M0XFNlwohK3sTzO9iJwvbYU-fuXRF0tvRpPPMGO6d_gJC_pUQwBT7wD8rKutpNTFHOHN3VqJ0A';
export async function subscribeToPush() {
    await askPermission();
    const registration = await navigator.serviceWorker.getRegistration();
    if (await registration.pushManager.getSubscription()) return;
    const subscribeOptions = {
        userVisibleOnly: true,
        applicationServerKey: urlBase64ToUint8Array(publicKey)
    };
    return registration.pushManager.subscribe(subscribeOptions).then(function (pushSubscription) {
        return sendSubscriptionToServer({ pushSubscription, uniqueid: Date.now() }, '/subscription')
    });
}

/**
* 将浏览器生成的subscription信息提交到服务端
* 服务端保存该信息用于向特定的客户端用户推送
* @param {string} body 请求体
* @param {string} url 提交的api路径，默认为/subscription
* @return {Promise}
*/
function sendSubscriptionToServer(body, url) {
    body = JSON.stringify(body)
    body = JSON.parse(body)
    body.uuid = uuid
    body = JSON.stringify(body)
    const requestConfig = {
        body: body,
        credentials: 'include',//为了在当前域名内自动发送 cookie ， 必须提供这个选项
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': document.getElementById("csrf-token").getAttribute("content")

        },
        mode: "cors",//请求的模式
        cache: "force-cache"
    }
    return fetch(url || '/subscription', requestConfig).then(res => res.json())
}

/**
 * 获取用户授权通知
 */
export function askPermission() {
    return Notification.requestPermission().then(function (result) {
        if (result !== 'granted') {
            throw new Error('We weren\'t granted permission.');
        }
        return result;
    })
}

/**
* 连接并打开存储，使用indexedDB
* @param {string} storeName 存储的名称
* @return {Promise}
*/
export function openStore(storeName, dbName = 'PWA_DB', version = 1) {
    return new Promise(function (resolve, reject) {
        if (!('indexedDB' in window)) {
            reject('don\'t support indexedDB');
        }
        var request = indexedDB.open(dbName, version);
        request.onerror = function (e) {
            console.log('连接数据库失败');
            reject(e);
        }
        request.onsuccess = function (e) {
            console.log('连接数据库成功');
            resolve(e.target.result);
        }
        request.onupgradeneeded = function (e) {
            console.log('数据库版本升级');
            var db = e.target.result;
            if (e.oldVersion === 0) {
                if (!db.objectStoreNames.contains(storeName)) {
                    var store = db.createObjectStore(storeName, {
                        keyPath: 'tag'
                    });
                    store.createIndex(storeName + 'Index', 'tag', { unique: false });
                    console.log('创建索引成功');
                }
            }
        }
    });
}

function getAndroidUUID() {
    // 使用localStorage来检查是否已经存在UUID，如果不存在则生成一个新的UUID
    uuid = localStorage.getItem('uuid');
    if (!uuid) {
        // 生成一个新的UUID
        uuid = 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            const r = (Math.random() * 16) | 0,
                v = c === 'x' ? r : (r & 0x3) | 0x8;
            return v.toString(16);
        });
        // 存储生成的UUID
        localStorage.setItem('uuid', uuid);
    }
    return uuid;
}

export const Sw = {
    register,
    update,
    unregister,
    subscribeToPush,
    syncData,
    installprompt,//
    forceUpdate,//更新缓存,
    postMessage
}
